package edu.ccut.saturn.studio.menuitem.page;

import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.MasterDetailsBlock;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

import edu.ccut.saturn.studio.core.util.eclipse.Messages;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnProjectUtil;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnDialogUtil;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnSWTUtils;
import edu.ccut.saturn.studio.menuitem.dialog.AddMenuItemDialog;
import edu.ccut.saturn.studio.menuitem.dialog.RenameDialog;
import edu.ccut.saturn.studio.menuitem.editor.MenuItemsEditor;
import edu.ccut.saturn.studio.menuitem.model.IMenu;
import edu.ccut.saturn.studio.menuitem.model.Menu;
import edu.ccut.saturn.studio.menuitem.model.MenuItem;
import edu.ccut.saturn.studio.menuitem.model.MenuItemModel;

public class MenuItemMasterDetailsBlock extends MasterDetailsBlock {
	private MenuItemsPage page;
	private TreeViewer treeViewer;
	private MenuItemsDetailsPage detailsPage;
	private Shell shell;
	private Menu menu;
	private Button addButton;
	private Button delButton;
	private Button upButton;
	private Button downButton;
	private Button renameButton;
	private MenuItemModel menuItemModel;
	private IProject project;
	private Section section;

	public MenuItemMasterDetailsBlock(MenuItemsPage menuItemsPage,
			MenuItemsEditor editor) {

		page = menuItemsPage;
		menuItemModel = menuItemsPage.getMenuItemModel();
		menu = menuItemModel.getMenu();
		project = SaturnProjectUtil.getProject(editor.getEditorInput());
	}

	protected void registerPages(DetailsPart detailsPart) {
		detailsPage = new MenuItemsDetailsPage(page, menuItemModel, project);
		detailsPart.registerPage(MenuItem.class, detailsPage);
	}

	protected void createMasterPart(final IManagedForm managedForm,
			Composite parent) {

		FormToolkit toolkit = managedForm.getToolkit();
		section = toolkit.createSection(parent, Section.DESCRIPTION
				| ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED
				| ExpandableComposite.TITLE_BAR);

		section.setText(Messages.getString("ScrolledPropertiesBlock.menutree")); //$NON-NLS-1$
		// section.setDescription("菜单");
		section.marginWidth = 10;
		section.marginHeight = 5;

		toolkit.createCompositeSeparator(section);

		Composite client = toolkit.createComposite(section, SWT.WRAP);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		client.setLayout(layout);
		Tree t = toolkit.createTree(client, SWT.FULL_SELECTION);
		GridData tree_data = new GridData(GridData.FILL_BOTH);
		tree_data.verticalSpan = 5;
		t.setLayoutData(tree_data);

		/*
		 * 为当前parent内，toolkit所创建的widget添加边框。如果widget已经设置了SWT.BORDER， 则不会再为其添加边框。
		 */
		toolkit.paintBordersFor(client);

		addButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.addnode"), SWT.PUSH); //$NON-NLS-1$
		addButton
				.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				doAdd();
			}
		});

		delButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.deletenode"), SWT.PUSH); //$NON-NLS-1$
		delButton
				.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		delButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				doDel();
			}
		});

		upButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.upmovenode"), SWT.PUSH); //$NON-NLS-1$
		upButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		upButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				doup();
			}
		});
		downButton = toolkit.createButton(client, Messages
				.getString("ScrolledPropertiesBlock.downmovenode"), SWT.PUSH); //$NON-NLS-1$
		downButton
				.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		downButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				dodown();
			}
		});

		renameButton = toolkit
				.createButton(
						client,
						Messages.getString("ScrolledPropertiesBlock.rename"), SWT.PUSH | SWT.ARROW_UP); //$NON-NLS-1$

		GridData gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
		gridData.widthHint = 63;
		gridData.heightHint = 22;
		renameButton.setLayoutData(gridData);
		renameButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent arg0) {
				openrenameDialog();

			}
		});

		/*
		 * IFormPart管理了整个Part的dirty state, saving, commit, focus, selection
		 * changes等等这样的事件。 并不是form中的每一个control都需要成为一个form
		 * part，最好将一组control通过实现IFormPart变成一个Part.
		 * 一般来说Section就是一个自然形成的组，所以Eclipse Form提供了一个SectionPart的实现，它包含一个Section
		 * 的实例。
		 */
		final SectionPart spart = new SectionPart(section, toolkit, SWT.NONE);

		managedForm.addPart(spart);

		treeViewer = new TreeViewer(t);
		treeViewer
				.setLabelProvider(new SaturnSWTUtils.SaturnLabelDefaultProvider() {
					public String getText(Object element) {
						if (element instanceof IMenu) {
							IMenu menuItem = (IMenu) element;
							return menuItem.getLabel();
						}

						return ""; //$NON-NLS-1$
					}
				});
		treeViewer
				.setContentProvider(new SaturnSWTUtils.SaturnTreeViewerDefaultContentProvider() {
					public Object[] getElements(Object inputElement) {
						if (inputElement instanceof IMenu) {
							IMenu menu = (IMenu) inputElement;
							return menu.getChildren().toArray();
						}

						return new Object[0];
					}

					public Object[] getChildren(Object parentElement) {
						if (parentElement instanceof IMenu) {
							IMenu menu = (IMenu) parentElement;
							return menu.getChildren().toArray();
						}

						return new Object[0];
					}

					public boolean hasChildren(Object element) {
						if (element instanceof IMenu) {
							IMenu menu = (IMenu) element;
							return !menu.getChildren().isEmpty();
						}

						return false;
					}
				});

		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				TreeSelection selection = (TreeSelection) treeViewer
						.getSelection();

				if (selection.getFirstElement() instanceof MenuItem) {
					MenuItem menuItemVO = (MenuItem) selection
							.getFirstElement();
 
					button(menuItemVO);

					managedForm.fireSelectionChanged(spart, event
							.getSelection());

				}
			}
		});

		
		treeViewer.setInput(menu);
		treeViewer.setSelection(new StructuredSelection(menu.getChildren().get(0)));

		delButton.setEnabled(false);
		upButton.setEnabled(false);
		downButton.setEnabled(false);
		renameButton.setEnabled(true);

		section.setClient(client);
	}

	private void doAdd() {
		TreeSelection selection = (TreeSelection) treeViewer.getSelection();
		MenuItem parent = null;

		if (selection.isEmpty()) {
			if (!this.menu.getChildren().isEmpty()) {
				SaturnDialogUtil.openInformation(shell, Messages
						.getString("ScrolledPropertiesBlock.pleasechooseparentnode")); //$NON-NLS-1$ 

				return;
			} else {
				parent = this.menu.getRoot();
			}
		}

		if (parent == null) {
			parent = (MenuItem) selection.getFirstElement();
		}
		AddMenuItemDialog addmenuTiemDialog = new AddMenuItemDialog(shell,
				this.project);

		int order = parent.getChildren().size() + 1;
		addmenuTiemDialog.setOrder(order + ""); //$NON-NLS-1$
		if (addmenuTiemDialog.open() == IDialogConstants.OK_ID) {
			MenuItem newMenuItem = new MenuItem();
			newMenuItem.setId(System.currentTimeMillis() + ""); //$NON-NLS-1$
			newMenuItem.setLabel(addmenuTiemDialog.getLabel());
			newMenuItem.setPath(addmenuTiemDialog.getPath());		
			newMenuItem.setOrder(addmenuTiemDialog.getOrder());
			newMenuItem.setParent(parent);
			newMenuItem.setParentId(parent.getId());//$NON-NLS-1$

			if (this.menu.getChildren().isEmpty()) {
				parent.addChild(newMenuItem);
				treeViewer.setInput(this.menu);
			} else {
				parent.addChild(newMenuItem);
				treeViewer.add(parent, newMenuItem);
				treeViewer.expandToLevel(parent, 1);
				treeViewer.setSelection(new StructuredSelection(newMenuItem.getParent()));
			}

			menuItemModel.addMenuItem(parent.getId(), newMenuItem);

		}
	}

	private void doDel() {
		TreeSelection selection = (TreeSelection) treeViewer.getSelection();
		if (selection.isEmpty()) {
			SaturnDialogUtil.openInformation(shell, Messages
					.getString("ScrolledPropertiesBlock.pleasechooseitemfordelete")); //$NON-NLS-1$ //$NON-NLS-2$
//		}
		} else {
			MenuItem menuItem = (MenuItem) selection.getFirstElement();

//			if (menuItem.getParent() == null) {
//				SaturnDialogUtil.openInformation(shell, Messages
//						.getString("ScrolledPropertiesBlock.10")); //$NON-NLS-1$ //$NON-NLS-2$
//				return;
//			}

			if (SaturnDialogUtil
					.openConfirm(
							shell,
							Messages.getString("MenuItemMasterDetailsBlock.deletenode"), Messages.getString("MenuItemMasterDetailsBlock.confirmdeletenode"))) { //$NON-NLS-1$ //$NON-NLS-2$

				int order = Integer.valueOf(menuItem.getOrder());
				MenuItem parent = menuItem.getParent();
				List<MenuItem> children = parent.getChildren();

				children.remove(menuItem);
				menuItemModel.deleteMenuItem(menuItem);

//				int size = children.size();
				for (MenuItem child : children) {
					int childOrder = Integer.parseInt(child.getOrder());

					if (childOrder > order) {
						String newOrder = childOrder - 1 + ""; //$NON-NLS-1$
						child.setOrder(newOrder);
						menuItemModel.changeMenuItemAttribute(child.getId(),
								MenuItemModel.MENUITEM_ATTRIBUTE_ORDER,
								newOrder);
					}
				}

					
								
				treeViewer.remove(menuItem);
//				if (size >= 1) {
//				treeViewer.setSelection(new StructuredSelection(children
//						.get(order - 2)));
//				}else {
//				treeViewer.setSelection(new StructuredSelection(parent));
//			}
				if (menuItem.getParentId().equals("1") & menuItem.getOrder().equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
					treeViewer.setSelection(new StructuredSelection(parent));
				} else {
					if (!menuItem.getOrder().equals("1")) { //$NON-NLS-1$
					treeViewer.setSelection(new StructuredSelection(children
							.get(order - 2)));
					}else {
					treeViewer.setSelection(new StructuredSelection(parent));
				}
				}
				// if (size >= 1) {
				// treeViewer.setSelection(new StructuredSelection(children
				// .get(order - 1)));
				// }else {
				// treeViewer.setSelection(new StructuredSelection(parent));
				// }
			}
		}
	}

	private void button(MenuItem menuItem) {
//		if (menuItem.getParent() == null) {
		if (menuItem.getId().equals("1")) { //$NON-NLS-1$
			delButton.setEnabled(false);
			upButton.setEnabled(false);
			downButton.setEnabled(false);
			renameButton.setEnabled(true);
		} else {
			delButton.setEnabled(true);
			renameButton.setEnabled(true);

			MenuItem parent = menuItem.getParent();

			int size = parent.getChildren().size();
			int order = Integer.parseInt(menuItem.getOrder());
			upButton.setEnabled(true);
			downButton.setEnabled(true);

			if (order == 1) {
				upButton.setEnabled(false);
				if (order == size) {
					downButton.setEnabled(false);
				}
			} else if (order == size) {
				downButton.setEnabled(false);
			} 
		}
	}

	private void doup() {
		TreeSelection selection = (TreeSelection) treeViewer.getSelection();
		if (selection.isEmpty()) {
			SaturnDialogUtil.openInformation(shell, Messages
					.getString("ScrolledPropertiesBlock.chooseupmoveitem")); //$NON-NLS-1$ 
		} else if (selection.getFirstElement() instanceof MenuItem) {
			MenuItem upMenuItem = (MenuItem) selection.getFirstElement();

			MenuItem parent = upMenuItem.getParent();
			List<MenuItem> children = parent.getChildren();

			int order = Integer.parseInt(upMenuItem.getOrder());

			children.remove(upMenuItem);
			children.add(order - 1, upMenuItem);
			MenuItem menuItem = null;

			for (MenuItem child : children) {
				int childOrder = Integer.parseInt(child.getOrder());

				if (childOrder == order - 1) {
					menuItem = child;
					break;
				}
			}

			if (menuItem != null) {
				children.remove(upMenuItem);
				int index = children.indexOf(menuItem);

				children.add(index, upMenuItem);

				upMenuItem.setOrder(order - 1 + ""); //$NON-NLS-1$
				menuItem.setOrder(order + ""); //$NON-NLS-1$
				this.menuItemModel.changeMenuItemAttribute(upMenuItem.getId(),
						MenuItemModel.MENUITEM_ATTRIBUTE_ORDER, upMenuItem
								.getOrder());
				this.menuItemModel.changeMenuItemAttribute(menuItem.getId(),
						MenuItemModel.MENUITEM_ATTRIBUTE_ORDER, menuItem
								.getOrder());
			}

			button(upMenuItem);

			treeViewer.remove(upMenuItem);
			treeViewer.insert(parent, upMenuItem, order - 2);
			treeViewer.setSelection(new StructuredSelection(upMenuItem));
		}
	}

	private void dodown() {
		TreeSelection selection = (TreeSelection) treeViewer.getSelection();
		if (selection.isEmpty()) {
			SaturnDialogUtil.openInformation(null, Messages
					.getString("ScrolledPropertiesBlock.pleasechoosedownmoveitem")); //$NON-NLS-1$ //$NON-NLS-2$
		} else if (selection.getFirstElement() instanceof MenuItem) {
			MenuItem downMenuItem = (MenuItem) selection.getFirstElement();
			MenuItem parent = downMenuItem.getParent();
			List<MenuItem> children = parent.getChildren();

			int order = Integer.parseInt(downMenuItem.getOrder());

			children.remove(downMenuItem);
			treeViewer.remove(downMenuItem);

			if (order < children.size()) {
				children.add(order + 1, downMenuItem);
				treeViewer.insert(parent, downMenuItem, order);
			} else {
				children.add(downMenuItem);
				treeViewer.add(parent, downMenuItem);
			}

			MenuItem menuItem = null;

			for (MenuItem child : children) {
				int childOrder = Integer.parseInt(child.getOrder());

				if (childOrder == order + 1) {
					menuItem = child;
					break;
				}
			}

			if (menuItem != null) {
				children.remove(downMenuItem);
				int index = children.indexOf(menuItem);

				children.add(index, downMenuItem);

				downMenuItem.setOrder(order + 1 + ""); //$NON-NLS-1$
				menuItem.setOrder(order + ""); //$NON-NLS-1$
				this.menuItemModel.changeMenuItemAttribute(
						downMenuItem.getId(),
						MenuItemModel.MENUITEM_ATTRIBUTE_ORDER, downMenuItem
								.getOrder());
				this.menuItemModel.changeMenuItemAttribute(menuItem.getId(),
						MenuItemModel.MENUITEM_ATTRIBUTE_ORDER, menuItem
								.getOrder());
			}

			button((MenuItem) selection.getFirstElement());

			treeViewer.setSelection(new StructuredSelection(downMenuItem));
		}
	}

	private void openrenameDialog() {
		TreeSelection selection = (TreeSelection) treeViewer.getSelection();
		if (selection.isEmpty()) {
			SaturnDialogUtil.openInformation(null, Messages
					.getString("ScrolledPropertiesBlock.pleasechoosedownmoveitem")); //$NON-NLS-1$ //$NON-NLS-2$
		} else if (selection.getFirstElement() instanceof MenuItem) {
			MenuItem menuItem = (MenuItem) selection.getFirstElement();
			RenameDialog lableDialog = new RenameDialog(shell);
			lableDialog.setName(menuItem.getLabel());
			if (lableDialog.open() == Window.OK) {
				menuItem.setLabel(lableDialog.getName());

				this.menuItemModel.changeMenuItemAttribute(menuItem.getId(),
						MenuItemModel.MENUITEM_ATTRIBUTE_LABEL, menuItem
								.getLabel());

				treeViewer.refresh(menuItem);
			}
		}
	}

	protected void createToolBarActions(IManagedForm managedForm) {
		final ScrolledForm form = managedForm.getForm();
		Action haction = new Action(
				Messages.getString("ScrolledPropertiesBlock.level"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.HORIZONTAL);
				form.reflow(true);
			}
		};
		haction.setChecked(true);
		haction
				.setToolTipText(Messages
						.getString("ScrolledPropertiesBlock.horizontalarray")); //$NON-NLS-1$

		Action vaction = new Action(
				Messages.getString("ScrolledPropertiesBlock.vertical"), Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.VERTICAL);
				form.reflow(true);
			}
		};
		vaction.setChecked(false);
		vaction
				.setToolTipText(Messages
						.getString("ScrolledPropertiesBlock.verticalarray")); //$NON-NLS-1$

		form.getToolBarManager().add(haction);
		form.getToolBarManager().add(vaction);
	}
}